package co.yixiang.yshop.module.order.service.rechargeorder;

import cn.hutool.core.util.ObjectUtil;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.framework.mybatis.core.util.MyBatisUtils;
import co.yixiang.yshop.module.member.api.user.MemberUserApi;
import co.yixiang.yshop.module.order.controller.admin.rechargeorder.vo.*;
import co.yixiang.yshop.module.order.convert.rechargeorder.RechargeOrderConvert;
import co.yixiang.yshop.module.order.dal.dataobject.rechargeorder.RechargeOrderDO;
import co.yixiang.yshop.module.order.dal.mysql.rechargeorder.RechargeOrderMapper;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.PaymentKit;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.WXPayUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.RECHARGE_ORDER_NOT_EXISTS;

/**
 * 充值订单 Service 实现类
 *
 * @author admin
 */
@Service
@Validated
@Slf4j
public class RechargeOrderServiceImpl implements RechargeOrderService {

    @Resource
    private RechargeOrderMapper rechargeOrderMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Value("${weixin.certurl}")
    private String cert_url;

    @Override
    public String createRechargeOrder(RechargeOrderCreateReqVO createReqVO) {
        // 插入
        RechargeOrderDO rechargeOrder = RechargeOrderConvert.INSTANCE.convert(createReqVO);
        rechargeOrderMapper.insert(rechargeOrder);
        // 返回
        return rechargeOrder.getId();
    }

    @Override
    public void updateRechargeOrder(RechargeOrderUpdateReqVO updateReqVO) {
        // 校验存在
        validateRechargeOrderExists(updateReqVO.getId());
        // 更新
        RechargeOrderDO updateObj = RechargeOrderConvert.INSTANCE.convert(updateReqVO);
        rechargeOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteRechargeOrder(String id) {
        // 校验存在
        validateRechargeOrderExists(id);
        // 删除
        rechargeOrderMapper.deleteById(id);
    }

    private void validateRechargeOrderExists(String id) {
        if (rechargeOrderMapper.selectById(id) == null) {
            throw exception(RECHARGE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public RechargeOrderDO getRechargeOrder(String id) {
        return rechargeOrderMapper.selectById(id);
    }

    @Override
    public List<RechargeOrderDO> getRechargeOrderList(Collection<String> ids) {
        return rechargeOrderMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<RechargeOrderRespVO> getRechargeOrderPage(RechargeOrderPageReqVO pageReqVO) {
//        PageResult<RechargeOrderRespVO> pageResult =
//                RechargeOrderConvert.INSTANCE.convertPage(rechargeOrderMapper.selectPage(pageReqVO));
//        if(CollectionUtils.isNotEmpty(pageResult.getList())){
//            List<Long> ids =
//                    pageResult.getList().stream().map(RechargeOrderRespVO::getUserId).collect(Collectors.toList());
//            List<MemberUserRespDTO> users = memberUserApi.getUsers(ids);
//            Map<Long, String> userMap =
//                    users.stream().collect(Collectors.toMap(MemberUserRespDTO::getId, MemberUserRespDTO::getNickname));
//            for (RechargeOrderRespVO vo :pageResult.getList()){
//                vo.setNickname(userMap.get(vo.getUserId()));
//            }
//        }
        // MyBatis Plus 查询
        IPage<RechargeOrderRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);
        rechargeOrderMapper.selectPageVO(mpPage,pageReqVO);
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    @Override
    public List<RechargeOrderDO> getRechargeOrderList(RechargeOrderExportReqVO exportReqVO) {
        return rechargeOrderMapper.selectList(exportReqVO);
    }

    @Override
    public void refund() throws Exception {
        List<RechargeOrderDO> rechargeOrderDOS = rechargeOrderMapper.selectList(new RechargeOrderExportReqVO().setStatus(1));
        for (RechargeOrderDO r : rechargeOrderDOS) {
            //退款资金来源-可用余额退款
            String refundAccount = "REFUND_SOURCE_RECHARGE_FUNDS";
            Map<String, String> params = new HashMap<>();
            params.put("appid", "wxf0713a10bbae8732");
            params.put("mch_id", "1558500071");
            params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
            //商户订单号和微信订单号二选一
            params.put("out_refund_no", r.getId());
            params.put("total_fee", new BigDecimal(r.getRechargeAmount()).multiply(BigDecimal.valueOf(100)).intValue() + "");
            params.put("refund_fee", new BigDecimal(r.getRechargeAmount()).multiply(BigDecimal.valueOf(100)).intValue() + "");
            params.put("refund_account", refundAccount);
            // 退款原因，若商户传入，会在下发给用户的退款消息中体现退款原因
            params.put("refund_desc", "退款");
            //退款回调 先不做
            //   params.put("notify_url", pc_refund_notify_url);
            //签名算法
            String sign = WXPayUtil.generateSignature(params, "zk7BHJJWThinkSztbI6zye9ZA70uNFtT");
            params.put("sign", sign);
            String xml = PaymentKit.toXml(params);
            String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml, cert_url, "1558500071");
            //加入微信支付日志
            Map<String, String> stringStringMap = PaymentKit.xmlToMap(xmlStr);
            log.info(stringStringMap.toString());
        }

    }

    @Override
    public Integer isPay(String id) {
        RechargeOrderDO orderDO = getRechargeOrder(id);
        if (ObjectUtil.isNull(orderDO)) {
            throw exception(RECHARGE_ORDER_NOT_EXISTS);
        }
        return getRechargeOrder(id).getStatus();
    }

}
